package com.ts.comm;


import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;

/**
 * 数字工具类
 * Created by xhc on 2017-3-22.
 */
public class SysNumber {

    /**
     * 汉语中数字大写
     */
    private static final String[] CN_UPPER_NUMBER = {"零", "壹", "贰", "叁", "肆",
            "伍", "陆", "柒", "捌", "玖"};
    /**
     * 汉语中货币单位大写，这样的设计类似于占位符
     */
    private static final String[] CN_UPPER_MONETRAY_UNIT = {"分", "角", "元",
            "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾",
            "佰", "仟"};
    /**
     * 特殊字符：整
     */
    private static final String CN_FULL = "整";
    /**
     * 特殊字符：负
     */
    private static final String CN_NEGATIVE = "负";
    /**
     * 金额的精度，默认值为2
     */
    private static final int MONEY_PRECISION = 2;
    /**
     * 特殊字符：零元整
     */
    private static final String CN_ZEOR_FULL = "零元" + CN_FULL;

    /**
     * 把输入的金额转换为汉语中人民币的大写
     *
     * @param numberOfMoney 输入的金额
     * @return 对应的汉语大写
     */
    public static String num2Money(BigDecimal numberOfMoney) {
        StringBuffer sb = new StringBuffer();
        // -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
        // positive.
        int signum = numberOfMoney.signum();
        // 零元整的情况
        if (signum == 0) {
            return CN_ZEOR_FULL;
        }
        //这里会进行金额的四舍五入
        long number = numberOfMoney.movePointRight(MONEY_PRECISION)
                .setScale(0, 4).abs().longValue();
        // 得到小数点后两位值
        long scale = number % 100;
        int numUnit = 0;
        int numIndex = 0;
        boolean getZero = false;
        // 判断最后两位数，一共有四中情况：00 = 0, 01 = 1, 10, 11
        if (!(scale > 0)) {
            numIndex = 2;
            number = number / 100;
            getZero = true;
        }
        if ((scale > 0) && (!(scale % 10 > 0))) {
            numIndex = 1;
            number = number / 10;
            getZero = true;
        }
        int zeroSize = 0;
        while (true) {
            if (number <= 0) {
                break;
            }
            // 每次获取到最后一个数
            numUnit = (int) (number % 10);
            if (numUnit > 0) {
                if ((numIndex == 9) && (zeroSize >= 3)) {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
                }
                if ((numIndex == 13) && (zeroSize >= 3)) {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
                }
                sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                sb.insert(0, CN_UPPER_NUMBER[numUnit]);
                getZero = false;
                zeroSize = 0;
            } else {
                ++zeroSize;
                if (!(getZero)) {
                    sb.insert(0, CN_UPPER_NUMBER[numUnit]);
                }
                if (numIndex == 2) {
                    if (number > 0) {
                        sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                    }
                } else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0)) {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                }
                getZero = true;
            }
            // 让number每次都去掉最后一个数
            number = number / 10;
            ++numIndex;
        }
        // 如果signum == -1，则说明输入的数字为负数，就在最前面追加特殊字符：负
        if (signum == -1) {
            sb.insert(0, CN_NEGATIVE);
        }
        // 输入的数字小数点后两位为"00"的情况，则要在最后追加特殊字符：整
        if (!(scale > 0)) {
            sb.append(CN_FULL);
        }
        return sb.toString();
    }

    /**
     * 格式化成百分比，生成String
     * double p=85695.365;生成8569536.5%
     */
    public static String percent(double f, int iDigit) {
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMaximumFractionDigits(iDigit);
        return nf.format(f);
    }

    /**
     * double 值四舍五入
     *
     * @param value
     * @param iDigit 小数位数
     * @return
     */
    public static double round(double value, int iDigit) {
        BigDecimal bd = new BigDecimal(value);
        BigDecimal nvalue = bd.setScale(iDigit, BigDecimal.ROUND_HALF_UP);
        return nvalue.doubleValue();
    }

    /**
     * 方法说明：验证是否是数字
     *
     * @param str
     * @return
     * @throw
     */
    public static boolean isNumber(String str) {
        try {
            if (SysString.isEmpty(str)) {
                return true;
            }

            str = str.replace(",", "").replace("%", "").replace("‰", "");

            double d = Double.parseDouble(str);
            return (!Double.isInfinite(d) && !Double.isNaN(d));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获得hashmap中key对应的值 转换成整形
     * @param map
     * @param sKey
     * @return
     */
    public static int getMapInt(Map<String, Object> map, String sKey) {
        return toInt(map.get(sKey));
    }
    /**
     * 获得hashmap中key对应的值 转换成double，默认保留两位小数
     * @param map
     * @param sKey
     * @return
     */
    public static double getMapDouble(Map<String, Object> map, String sKey) {
        return toDouble(map.get(sKey));
    }

    /**
     * 转换为double类型
     * @param obj
     * @return
     */
    public static double toDouble(Object obj) {
        double d = 0;
        d = toDouble(obj, 2);
        return d;
    }
    /**
     * 转换为double类型
     * @param obj
     * @param iDigit  保留几位小数
     * @return
     */
    public static double toDouble(Object obj, int iDigit) {
        double d = 0;
        if (obj != null && !"".equals(obj.toString())) {
            try {
                String str = obj.toString();
                str = str.replace(",", "");
                if (str.indexOf("%") != -1) {
                    d = Double.parseDouble(str.replace("%", "")) / 100;
                } else if (str.indexOf("‰") != -1) {
                    d = Double.parseDouble(str.replace("‰", "")) / 1000;
                } else {
                    d = Double.parseDouble(str);
                    BigDecimal big = new BigDecimal(d);
                    d = big.setScale(iDigit, BigDecimal.ROUND_HALF_UP).doubleValue();
                }
            } catch (Exception e) {
                d = 0;
            }
        }
        return d;
    }

    /**
     * number类型转换为字符串
     * @param obj
     * @return
     */
    public static String toString(Object obj) {

        String str = "";
        try {
            if (obj == null) {
                str = "";
            } else {
                if (obj instanceof Double || obj instanceof Float) {
                    str = String.format("%f", obj);
                } else {
                    str = obj.toString();
                }
                if (str.equalsIgnoreCase("NaN") || str.equalsIgnoreCase("Infinitely")) {
                    str = "";
                }
            }
        } catch (Exception e) {

        }
        return str;
    }
    /**
     * number类型转换为int
     * @param obj
     * @return
     */
    public static int toInt(Object obj) {
        try {
            double d = toDouble(obj);
            if (!Double.isInfinite(d) && !Double.isNaN(d)) {
                BigDecimal bd = new BigDecimal(d);
                return bd.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
            }
        } catch (Exception e) {
            return 0;
        }
        return 0;
    }
    /**
     * 计算两数百分数
     * @param divisor 除数
     * @param dividend 被除数
     * @return  51.2%
     */
    public static String getPercent(int divisor, int dividend){
        DecimalFormat decimalFormat = new DecimalFormat();
        decimalFormat.setMaximumFractionDigits(1);
        decimalFormat.setMinimumFractionDigits(1);
        if(divisor!=0){
            String percent = decimalFormat.format(dividend * 100.00 / divisor) + "%";
            return percent;
        }else{
            String percent = decimalFormat.format(0.00) + "%";
            return percent;
        }
    }

    /**
     * 产生指定范围[min-max]之间的随机数
     *
     * @return
     */
    public static int random(int min, int max) {
        return (int) Math.round(Math.random() * (max - min) + min);
    }

	/**
	 * 将一个数拆成2的n次方的和
	 * @param number
	 * @return
	 */
	public static List<Integer> toBinaryList(int number){
        List<Integer> list = new ArrayList<Integer>();
        String binaryString = Integer.toBinaryString(number);
        for(int i = 0 ; i < binaryString.length() ; i ++){
        	if(binaryString.charAt(i) == '1'){
        		list.add((int) Math.pow(2,i));
			}
		}
        return list;
    }

}
